<template>
  <div ref="scrollContainer" class="infinite-scroll-container">
    <slot />
    <div v-if="loading" class="loading-indicator">
      Loading...
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted, watch, nextTick } from 'vue'

const props = defineProps({
  scrollDisabled: {
    type: Boolean,
    default: false
  },
  scrollDelay: {
    type: Number,
    default: 200
  },
  scrollDistance: {
    type: Number,
    default: 0
  },
  scrollImmediate: {
    type: Boolean,
    default: true
  }
})

const emit = defineEmits(['load'])

const scrollContainer = ref(null)
const loading = ref(false)
let throttleTimeout = null
let isDestroyed = false

const checkScrollPosition = () => {
  if (!scrollContainer.value || props.scrollDisabled) return

  const { scrollTop, scrollHeight, clientHeight } = scrollContainer.value
  const triggerAt = scrollHeight - props.scrollDistance

  if (scrollTop + clientHeight >= triggerAt) {
    loadMore()
  }
}

const loadMore = async () => {
  if (loading.value || props.scrollDisabled) return

  loading.value = true
  try {
    await emit('load')
    // 加载完成后再次检查是否需要继续加载
    nextTick(() => {
      if (!isDestroyed) checkScrollPosition()
    })
  } finally {
    loading.value = false
  }
}

const handleScroll = () => {
  if (props.scrollDisabled || loading.value) return

  if (throttleTimeout) {
    clearTimeout(throttleTimeout)
  }

  throttleTimeout = setTimeout(() => {
    checkScrollPosition()
  }, props.scrollDelay)
}

onMounted(() => {
  if (props.scrollImmediate) {
    nextTick(checkScrollPosition)
  }

  window.addEventListener('scroll', handleScroll, true)
})

onUnmounted(() => {
  isDestroyed = true
  window.removeEventListener('scroll', handleScroll, true)
  if (throttleTimeout) {
    clearTimeout(throttleTimeout)
  }
})

watch(() => props.scrollDisabled, (newVal) => {
  if (!newVal) {
    nextTick(checkScrollPosition)
  }
})
</script>

<style scoped>
.infinite-scroll-container {
  overflow-y: auto;
}

.loading-indicator {
  padding: 1rem;
  text-align: center;
  color: #666;
}
</style>